package com.faxsun.core.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import mblog.core.persist.dao.UserDao;
import mtons.modules.pojos.Page;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.faxsun.core.persist.dao.LiveDao;
import com.faxsun.core.persist.dao.LiveMsgDao;
import com.faxsun.core.persist.entity.LiveManagerPO;
import com.faxsun.core.persist.entity.LiveMsgPO;
import com.faxsun.core.persist.entity.LivePO;
import com.faxsun.core.persist.entity.UserPO;
import com.faxsun.core.service.LiveAdminService;
import com.faxsun.core.service.LiveMsgService;

public class LiveMsgServiceImpl implements LiveMsgService {

	private static final Logger log = LoggerFactory
			.getLogger(LiveMsgServiceImpl.class);

	@Autowired
	private LiveMsgDao liveMsgDao;

	@Autowired
	private UserDao userDao;

	@Autowired
	private LiveDao liveDao;

	@Autowired
	private LiveAdminService liveAdminService;

	@Transactional
	@Override
	public LiveMsgPO save(LiveMsgPO entity) {
		// validate entity fields
		long channelId = entity.getChannel().getId();
		LivePO channel = liveDao.get(channelId);

		if (channel == null) {
			return null;
		}
		Date date = new Date(System.currentTimeMillis());
		Date start = channel.getStartTime();
		Date end = channel.getEndTime();
		if ((start != null && date.before(start))
				|| (end != null && date.after(end))) {
			log.debug("The channel " + channel.getTopic() + " is not live");
			return null;
		}
		// validate user
		UserPO userPO = entity.getSender();
		userPO = userDao.get(userPO.getId());
		// userPO = userDao.getByThirdId(userPO.getThirdLogin());
		if (userPO == null) {
			return null;
		}

		// 验证发送用户的权限
		LiveManagerPO liveManagerPO = liveAdminService.getLiveManager(
				userPO.getId(), channelId);
		if (liveManagerPO == null) {
			return null;
		}

		entity.setSender(userPO);
		entity.setChannel(channel);
		liveMsgDao.save(entity);
		return entity;
	}

	@SuppressWarnings("unchecked")
	@Transactional
	@Override
	public List<LiveMsgPO> listPage(Page page, long channelId, long startMsgId) {
		List<LiveMsgPO> result = new ArrayList<LiveMsgPO>();

		if (!isValideChannelId(channelId)) {
			result = null;
		}

		if (result != null) {
			this.liveMsgDao.listHisotry(page, channelId, startMsgId);
			result.addAll((Collection<LiveMsgPO>) page.getResults());
			for (LiveMsgPO msg : result) {
				// for lazy load
				msg.getChannel().getId();
				msg.getSender().getThirdLogin();
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Transactional
	@Override
	public List<LiveMsgPO> listNewMsg(Page page, long channelId, long startMsgId) {
		List<LiveMsgPO> result = new ArrayList<LiveMsgPO>();

		if (!isValideChannelId(channelId)) {
			result = null;
		}

		if (result != null) {
			if (startMsgId > 0) {
				page.setMaxResults(Integer.MAX_VALUE);
			} else {
				page.setMaxResults(30);
			}
			this.liveMsgDao.listNew(page, channelId, startMsgId);
			result.addAll((Collection<LiveMsgPO>) page.getResults());
		}

		return result;
	}

	/**
	 * 验证channelId是否合法：数据库中存在
	 * 
	 * @param channelId
	 * @return
	 */
	@Transactional
	public boolean isValideChannelId(long channelId) {
		LivePO channel = null;
		if (channelId > 0) {
			channel = findChannelById(channelId);
		}
		return channel != null;
	}

	@Transactional
	@Cacheable(value = "liveCache", key = "'channel' + #channelId")
	public LivePO findChannelById(long channelId) {
		LivePO channel = null;
		channel = this.liveDao.get(channelId);
		return channel;
	}

	/**
	 * 验证channelId是否合法
	 */
	@Override
	@Transactional
	public boolean isValideChannelId(String channelId) {
		Long channelid = 0L;
		if (!StringUtils.isEmpty(channelId)) {
			try {
				channelid = Long.parseLong(channelId);
			} catch (Exception e) {
				return false;
			}
		}

		return isValideChannelId(channelid);
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	@Cacheable(value = "liveCache", key = "'getFinalBookPages' + #channelId")
	public List<String> getFinalBookPages(long channelId, LivePO livePO,
			UserPO admin) {
		Page page = new Page();
		page.setMaxResults(Integer.MAX_VALUE);

		List<LiveMsgPO> allMsgs = listPage(page, channelId, Long.MAX_VALUE);

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		List<String> ret = new ArrayList<String>();

		String coverImg = livePO.getCoverImage();
		ret.add(coverImg);

		String topic = livePO.getTopic();
		String topicStart = sdf.format(livePO.getStartTime());
		String topicEnd = sdf.format(livePO.getEndTime());
		ret.add(topic + LiveMsgService.bookPageToken + topicStart
				+ LiveMsgService.bookPageToken + topicEnd
				+ LiveMsgService.bookPageToken + admin.getAvatar()
				+ LiveMsgService.bookPageToken + admin.getName());

		String desc = livePO.getDescription();
		ret.add("" + LiveMsgService.bookPageToken + desc);

		for (LiveMsgPO po : allMsgs) {
			@SuppressWarnings("rawtypes")
			Map lmjson = (Map) JSON.parse(po.getContent());

			String msgDate = sdf.format(po.getDate());
			String text = (String) lmjson.get("text");
			if (text != null && !text.isEmpty()) {
				ret.add(msgDate + LiveMsgService.bookPageToken
						+ text
						+ LiveMsgService.bookPageToken
						+ po.getSender().getAvatar()// admin.getAvatar()
						+ LiveMsgService.bookPageToken
						+ po.getSender().getName());// admin.getName());
			} else {
				ret.add(msgDate + LiveMsgService.bookPageToken
						+ "有图有真相"
						+ LiveMsgService.bookPageToken
						+ po.getSender().getAvatar()// admin.getAvatar()
						+ LiveMsgService.bookPageToken
						+ po.getSender().getName());// admin.getName());
			}

			List<String> urls = (List<String>) lmjson.get("url");
			if (urls != null && urls.size() > 0) {
				for (String url : urls) {
					ret.add(url);
				}
			}
		}

		ret.add("http://www.faxsun.com/faxsun-info/src/img/wechatbarcode.png");
		return ret;
	}

	@Override
	@Transactional
	@Cacheable(value = "liveCache", key = "'findMsgDateById' + #channelId")
	public List<Date> findMsgDateById(long channelId) {
		List<Date> dates = liveMsgDao.findMsgDateById(channelId);
		return dates;
	}

	@Override
	@Transactional
	@Cacheable(value = "liveCache", key = "'findById' + #msgid")
	public LiveMsgPO findById(Long msgid) {
		return liveMsgDao.get(msgid);
	}

	@Override
	@Transactional
	public void incrementThumbup(long channelId) {
		LiveMsgPO po = liveMsgDao.get(channelId);
		po.setThumbsup(po.getThumbsup() + 1);
		liveMsgDao.update(po);
	}

	@Override
	@Transactional
	public void decrementThumbup(long channelId) {

		LiveMsgPO po = liveMsgDao.get(channelId);
		po.setThumbsup(po.getThumbsup() - 1);
		liveMsgDao.update(po);
	}

	@Override
	@Transactional
	public void incrementComment(long channelId) {
		LiveMsgPO po = liveMsgDao.get(channelId);
		if (po != null) {
			po.setComments(po.getComments() + 1);
			liveMsgDao.update(po);
		}

	}

	@Override
	@Transactional
	public void decrementComment(long channelId) {
		LiveMsgPO po = liveMsgDao.get(channelId);
		if (po != null) {
			po.setComments(po.getComments() - 1);
			liveMsgDao.update(po);
		}
	}
}
